<?php
/**
 * This Source Code Form is subject to the terms
 * of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/**
 * Class for currency conversions
 *
 * Conversions at http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
 * Accepted currency codes:
 * EUR,USD,JPY,BGN,CZK,DKK,EEK,GBP,HUF,LTL,LVL,PLN,RON,SEK,CHF,NOK,HRK
 * RUB,TRY,AUD,BRL,CAD,CNY,HKD,IDR,INR,KRW,MXN,MYR,NZD,PHP,SGD,THB,ZAR
 *
 * @see http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
 * 
 * @author Albert Ovide <albert at ovide dot net>
 * @since 7-05-2010
 * @version 1.0
 */
class CurrencyConverter {
	//Updated currency conversion values
	const URL='http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml';
	//Default value for the temp xml
	const pathXML='../tmp/currency.xml';
	//All conversion constants are based on EUR
	const general='EUR';
	/**
	 * @var Array
	 */
	private $rates;
	/**
	 * @var string
	 */
	private $xmlFile;
	/**
	 * @param string $path The path to save the temp xml
	 */
	public function __construct($path=self::pathXML){
		$this->xmlFile=$path;
		$objDOM = new DOMDocument();
		if(@$objDOM->load($this->xmlFile)){
			$this->rates = $objDOM->getElementsByTagName('Cube');
			if(!$this->isUpdated())$this->updateXml(self::URL);
		}
		else $this->updateXml(self::URL);
	}
	/**
	 * Updates the xml
	 * @param string $URL
	 */
	private function updateXml($URL){
		$objDOM=new DOMDocument();
		if($objDOM->load($URL)){
			$this->rates=$objDOM->getElementsByTagName('Cube');
			//if(!$this->isUpdated())throw new Exception('XML is out of date');
		}else throw new Exception('Can\'t get xml file from '.$URL);
		$objDOM->save($this->xmlFile);
	}
	/**
	 * @return boolean True if the xml is updated
	 */
	private function isUpdated(){
		foreach($this->rates as $dada){
			if(($data=$dada->getAttributeNode('time'))){
				$avui=date('Y\-m\-d');
				if($data->value==$avui)return true;
				else return false;
				break;
			}
		}
	}
	/**
	 * Gets the constant for currency conversion
	 * @example
	 * echo '1€ -> $'.$converter->getRate('EUR','USD');
	 *
	 * Will print:
	 * 1€ -> $1.2764
	 * @param string $from Orig. currency code
	 * @param string $to Dest. currency code
	 * @return float Currency conversion constant
	 * @throws Exception If any currency code don't exist
	 * @see http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
	 */
	public function getRate($from,$to){
		$rateF=0.0;
		$rateT=0.0;
		if($from==self::general)$rateF=1.0;
		if($to==self::general)$rateT=1.0;
		foreach($this->rates as $rate){
			if(($curr=$rate->getAttributeNode('currency'))!=FALSE){
				if($curr->value==$from)$rateF=(float)$rate->getAttributeNode('rate')->value;
				if($curr->value==$to)$rateT=(float)$rate->getAttributeNode('rate')->value;
			}
			if(($rateF!=0.0)&&($rateT!=0.0))break;
		}
		if(($rateF==0.0)||($rateT==0.0))
			throw new Exception ('Currency code not found');
		else return (float)($rateT/$rateF);
	}
}

